package com.hb.trade.server.center.au.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hb.core.pojo.UserConfig;
import com.hb.core.pojo.center.au.dto.RoleDTO;
import com.hb.core.pojo.center.au.entity.User;
import com.hb.core.pojo.center.au.mapper.RoleMapper;
import com.hb.core.pojo.center.au.entity.Role;
import com.hb.core.pojo.enums.RoleSignEnum;
import com.hb.core.pojo.enums.RoleTypeEnum;
import com.hb.trade.server.center.au.manager.RoleManager;
import com.hb.trade.server.center.au.service.RoleResourceService;
import com.hb.trade.server.center.au.service.RoleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hb.trade.server.center.au.service.UserService;
import org.fzzn.core.model.enums.LogicEnum;
import org.fzzn.core.util.Enums;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 角色信息表 服务实现类
 *
 * @author zhaojk
 * @since 2021-11-29
 */
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {

    protected final UserService userService;
    protected final RoleResourceService roleResourceService;

    public RoleServiceImpl(UserService userService,
                           RoleResourceService roleResourceService) {
        this.userService = userService;
        this.roleResourceService = roleResourceService;
    }

    /**
     * 获取指定的业务角色(总公司管理员)
     *
     * @param roleSign
     * @return
     * @see RoleSignEnum
     */
    @Override
    public Role getRoleByRoleSign(RoleSignEnum roleSign) {
        if (roleSign == null) {
            return null;
        }
        QueryWrapper<Role> wrapper = Role.wrapper();
        wrapper.lambda()
                .eq(Role::getRoleSign, roleSign.getCode())
                .eq(Role::getRoleType, RoleTypeEnum.HEAD_COMPANY_MANAGER.getCode())
                .last("limit 1");
        return getOne(wrapper);
    }

    /**
     * 获取指定角色类型的系统角色信息
     * 当roleType=7时(即总公司管理员时), 必须指定roleSign
     * roleType为其他值时, roleSign不需要传
     *
     * @param roleType
     * @return
     * @see RoleTypeEnum
     */
    @Override
    public Role getRoleByRoleType(RoleTypeEnum roleType, RoleSignEnum roleSignEnum) {
        if (roleType == null) {
            return null;
        }
        QueryWrapper<Role> wrapper = Role.wrapper();
        wrapper.lambda().eq(Role::getRoleType, roleType.getCode());

        // 如果获取总公司管理员, 必须指定roleSign
        if (roleType == RoleTypeEnum.HEAD_COMPANY_MANAGER) {
            if (roleSignEnum == null) {
                return null;
            }
            wrapper.lambda().eq(Role::getRoleSign, roleSignEnum.getCode());
        } else {
            wrapper.lambda().isNull(Role::getRoleSign);
        }
        wrapper.last("limit 1");
        return getOne(wrapper);
    }

    /**
     * 获取指定角色类型的非业务角色的系统角色信息
     *
     * @param roleType
     * @return
     * @see RoleTypeEnum
     */
    @Override
    public Role getRoleByRoleType(RoleTypeEnum roleType) {
        return getRoleByRoleType(roleType, null);
    }

    /**
     * 分页查询角色列表
     *
     * @param rolePage
     * @param roleDTO
     * @return
     */
    @Override
    public Page<Role> pageRoles(Page<RoleDTO> rolePage, RoleDTO roleDTO) {
        return baseMapper.pageRoles(rolePage, roleDTO);
    }

    /**
     * 分页查询角色列表, 后台管理用
     *
     * @param rolePage
     * @param roleDTO
     * @return
     */
    @Override
    public Page<Role> pageManagementRoles(Page<RoleDTO> rolePage, RoleDTO roleDTO) {
        return baseMapper.pageManagementRoles(rolePage, roleDTO);
    }

    /**
     * 公司信息添加角色信息
     *
     * @param user              用户对象
     * @param user#orgId        企业ID
     * @param user#accountLevel 账号等级
     * @param user#userConfig   用户配置
     * @param roleSign          业务角色类型
     * @return
     * @see RoleSignEnum
     */
    @Transactional(rollbackFor = Throwable.class)
    @Override
    public boolean initData(User user, int roleSign) {
        if (user == null) {
            return false;
        }
        Long orgId = user.getOrgId();
        if (orgId == null) {
            return false;
        }
        UserConfig userConfig = user.getUserConfig();
        if (userConfig == null) {
            userConfig = new UserConfig();
        }
        Integer canCreateBranchCompany = userConfig.getCanCreateBranchCompany();
        if (canCreateBranchCompany == null) {
            canCreateBranchCompany = LogicEnum.NO.getCode();
        }
        return initData(orgId, canCreateBranchCompany, user.getAccountLevel(), roleSign);
    }

    /**
     * 公司信息添加初始化角色信息
     * 分公司管理员, 部门负责人, 项目经理
     *
     * @param orgId        需要添加的企业ID
     * @param accountLevel 账号等级(1为一级帐号, 2为二级账号, 以此类推...)
     * @return
     */
    @Transactional(rollbackFor = Throwable.class)
    @Override
    public boolean initData(Long orgId, Integer canCreateBranchCompany, int accountLevel, int roleSign) {
        if (orgId == null) {
            return false;
        }

        RoleSignEnum roleSignEnum = Enums.of(RoleSignEnum.class, roleSign);
        switch (accountLevel) {
            case 1: // 一级帐号/总公司帐号
                // 投标人角色没有分公司管理员
                if (roleSignEnum != RoleSignEnum.BIDDER) {
                    // 拥有总公司的权限
                    if (Enums.equals(LogicEnum.YES, canCreateBranchCompany)) {
                        // 生成分公司管理员
                        RoleManager branchManager = RoleManager.get(orgId, roleSign, RoleTypeEnum.BRANCH_COMPANY_MANAGER);

                        // 插入数据之前验证是否存在
                        boolean existsBranchManager = exists(orgId, roleSign, RoleTypeEnum.BRANCH_COMPANY_MANAGER);
                        // 不存在时添加角色
                        if (!existsBranchManager) {
                            save(branchManager);
                            // 保存信息之后默认授权
                            roleResourceService.updatePermissionsDefault(branchManager.getId(), roleSign, RoleTypeEnum.BRANCH_COMPANY_MANAGER);
                        }
                    }
                }

            case 2: // 二级帐号/分公司帐号
                // 生成部门负责人
                RoleManager deptManager = RoleManager.get(orgId, roleSign, RoleTypeEnum.DEPT_MANAGER);

                // 插入数据之前验证是否存在
                boolean existsDeptManager = exists(orgId, roleSign, RoleTypeEnum.DEPT_MANAGER);
                // 不存在时添加角色
                if (!existsDeptManager) {
                    save(deptManager);
                    // 保存信息之后默认授权
                    roleResourceService.updatePermissionsDefault(deptManager.getId(), roleSign, RoleTypeEnum.DEPT_MANAGER);
                }

                // 生成项目经理
                RoleManager projManager = RoleManager.get(orgId, roleSign, RoleTypeEnum.PROJECT_MANAGER);

                // 插入数据之前验证是否存在
                boolean existsProjManager = exists(orgId, roleSign, RoleTypeEnum.PROJECT_MANAGER);
                // 不存在时添加角色
                if (!existsProjManager) {
                    save(projManager);
                    // 保存信息之后默认授权
                    roleResourceService.updatePermissionsDefault(projManager.getId(), roleSign, RoleTypeEnum.PROJECT_MANAGER);
                }

            default:
                break;
        }

        return true;
    }

    /**
     * 判断指定的角色类型是否存在
     *
     * @param orgId
     * @param roleSign
     * @param roleTypeEnum
     * @return true: 存在, false: 不存在
     */
    @Override
    public boolean exists(Long orgId, int roleSign, RoleTypeEnum roleTypeEnum) {
        if (orgId == null) {
            return false;
        }
        RoleSignEnum signEnum = Enums.of(RoleSignEnum.class, roleSign);
        if (signEnum == null) {
            return false;
        }
        if (roleTypeEnum == null) {
            return false;
        }
        QueryWrapper<Role> wrapper = Role.wrapper();
        wrapper.eq("org_id", orgId).eq("role_sign", roleSign).eq("role_type", roleTypeEnum.getCode());
        return count(wrapper) > 0;
    }

    /**
     * 根据手机号查询全部非投标人角色ID
     *
     * @param phone
     * @return
     */
    @Override
    public List<Long> listRoleIdByPhone(String phone, Integer roleSign) {
        List<Long> roles = this.baseMapper.listRoleIdByPhone(phone, roleSign);
        return roles;
    }

}
